package lion.framework.core.task.rule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import lion.dev.lang.MapJ;
import lion.dev.text.Formater;
import lion.framework.core.task.anno.TimerRule;

import org.apache.commons.lang.StringUtils;

/**
 * 日期集合，一组通过逗号日期分隔的日期列表
 *
 * <pre>
 * <schedule name="thisisanothertest" rule="dateset" task="TestTask" dateset="2013-5-1 22:00:00,2013-5-2 8:30:00" stoponerror="true" />
 * </pre>
 *
 * <pre>
 * time   2013年9月18日
 * mail   hl_0074@sina.com
 * </pre>
 *
 * @author lion
 */
@TimerRule("dateset")
public class DateSetTimerRule extends AbstractTimerRule {

	private String expression;
	private List<Date> dates = new ArrayList<>();

	public DateSetTimerRule(MapJ config) {

		super(config);
		expression = config.getString("dateset");
		if (StringUtils.isBlank(expression)) { return; }
		String[] exps = expression.split(",");
		for (String exp : exps) {
			if (StringUtils.isBlank(exp)) {
				continue;
			}
			Date date = Formater.parseDate("yyyy-MM-dd HH:mm:ss", exp);
			if (date != null) {
				dates.add(date);
			}
		}
		Collections.sort(dates, new DateCompare());
	}

	public void addScheduleDate(Date date) {

		dates.add(date);
		Collections.sort(dates, new DateCompare());
	}

	public void addScheduleDate(List<Date> dates) {

		this.dates.addAll(dates);
		Collections.sort(this.dates, new DateCompare());
	}

	public Date getStartTime() {

		if (this.dates.isEmpty()) { return null; }
		return this.dates.get(0);
	}

	public Date getEndTime() {

		if (this.dates.isEmpty()) { return null; }
		return this.dates.get(this.dates.size() - 1);
	}

	public Date getNextRunTime(Date lastDate) {

		if (lastDate == null) {
			lastDate = new Date();
		}
		for (Date date : this.dates) {
			if (date.getTime() >= lastDate.getTime()) { return date; }
		}
		return null;
	}

	@Override
	public boolean isExpired() {

		if (this.dates.isEmpty()) { return true; }
		if (expression.indexOf("-") < 0) { return false; }

		Date date = this.getEndTime();
		Date now = new Date();

		return now.getTime() > date.getTime();
	}

	@Override
	public boolean checkRunTime(Date last) {

		Date now = new Date();
		// check start time
		if (this.getStartTime() != null && now.getTime() < this.getStartTime().getTime()) { return false; }

		// check end time
		if (this.getEndTime() != null && now.getTime() > this.getEndTime().getTime()) { return false; }

		// check is time to run
		Date next = this.getNextRunTime(last);
		if (next == null) { return false; }

		if (now.getTime() >= next.getTime()) { return true; }

		return false;
	}

}
